﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BZLib.Global;

namespace BZLib
{
    namespace Network
    {
        // All - DataSent classes must implement this interface.
        public interface IMessageDataSent : IMessageData, IPackable
        {
        }

        public class AliveDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.Alive ; }

            // No data sent in this message

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                return str;
            }
        }
        public class CaptureFlagDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.CaptureFlag ; }

            // Data sent in this message
            public TeamName Team;

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackUShort((ushort)Team);

                return str;
            }
        }
        public class ChatMessageDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.ChatMessage ; }

            // Data sent in this message
            public int Recipient;
            public string Text;

            public ChatMessageDataSent()
            {
                Recipient = (int)NetPlayer.All;
                Text = "";
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackUByte((byte)Recipient);
                str.PackString(Text, 128);

                return str;
            }
        }
        public class DropFlagDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.DropFlag ; }

            // Data sent in this message
            public Point Position;

            public DropFlagDataSent()
            {
                Position = new Point();
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackFloat((float)Position.X);
                str.PackFloat((float)Position.Y);
                str.PackFloat((float)Position.Z);

                return str;
            }
        }
        public class EnterDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.Enter; }

            // Data sent in this mesage
            public PlayerType Type;
            public TeamName Team;
            public string Callsign;
            public string Email;
            public string Token;
            public string Version;

            public EnterDataSent()
            {
                Type = PlayerType.Tank;
                Callsign = "";
                Email = "";
                Token = "";
                Version = "BZLib Client";
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackUShort((ushort)Type);
                str.PackUShort((ushort)Team);
                str.PackString(Callsign, 32);
                str.PackString(Email, 128);
                str.PackString(Token, 22);
                str.PackString(Version, 60);


                return str;
            }
        }
        public class ExitDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.Exit ; }

            // No data sent in this message

            public ExitDataSent()
            {
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                return str;
            }
        }
        public class GetWorldDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.GetWorld ; }

            // Data sent in this message
            uint Progress;

            public GetWorldDataSent()
            {
                Progress = 0;
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackUInt(Progress);

                return str;
            }
        }
        public class GrabFlagDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.GrabFlag ; }

            // Data sent in this message
            public int FlagID;

            public GrabFlagDataSent()
            {
                FlagID = -1;
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackUShort((ushort)FlagID);

                return str;
            }
        }
        public class KilledDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.Killed ; }

            // Data sent in this message
            public int Killer;
            public DeathReason Reason;
            public int ShotID;
            public string Flag;
            public int Physics;

            public KilledDataSent()
            {
                Killer = -1;
                Reason = DeathReason.Last;
                ShotID = -1;
                Flag = "";
                Physics = -1;
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackUByte((byte)Killer);
                str.PackUShort((ushort)Reason);
                str.PackShort((short)ShotID);
                str.PackString(Flag, 2);

                if (Reason == DeathReason.PhysicsDriver)
                    str.PackInt(Physics);

                return str;
            }
        }
        public class LagPingDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.LagPing ; }

            // No data sent in this message

            public LagPingDataSent()
            {
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();

                return str;
            }
        }
        public class NegotiateFlagsDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.NegotiateFlags ; }

            // Data sent in this message
            List<string> Flags;

            public NegotiateFlagsDataSent()
            {
                Flags = new List<string>();
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();

                foreach (string flag in Flags)
                {
                    str.PackString(flag, 2);
                }

                return str;
            }
        }
        public class NewRabbitDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.NewRabbit ; }

            // No data sent in this message

            public NewRabbitDataSent()
            {
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();

                return str;
            }
        }
        public class PauseDataSent : IMessageDataSent
        {
            NetMessage IMessageData.GetMessageType() { return NetMessage.Pause ; }

            // Data sent in this message
            public bool Paused;

            public PauseDataSent()
            {
                Paused = false;
            }

            BinaryString IPackable.Pack()
            {
                BinaryString str = new BinaryString();
                str.PackUByte((byte)(Paused ? 1 : 0));

                return str;
            }
        }
    }
}
